package org.openatom.ubml.model.vo.definition.json.operation;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import org.openatom.ubml.model.common.definition.cef.json.SerializerUtils;
import org.openatom.ubml.model.vo.definition.action.ViewModelAction;
import org.openatom.ubml.model.vo.definition.action.ViewModelActionType;
import org.openatom.ubml.model.vo.definition.collection.VMActionCollection;

import java.io.IOException;

/**
 * The Josn Deserializer Of View Model Action Collection
 *
 * @ClassName: VmActionCollectionDeserializer
 * @Author: Benjamin Gong
 * @Date: 2021/1/11 17:13
 * @Version: V1.0
 */
public class VmActionCollectionDeserializer extends JsonDeserializer<VMActionCollection> {
    @Override
    public VMActionCollection deserialize(JsonParser parser, DeserializationContext deserializationContext) {
        VMActionCollection collection = createCollection();
        if (SerializerUtils.readNullObject(parser)) {
            return collection;
        }
        try {
            JsonNode nodeList = new ObjectMapper().readTree(parser);

            if (nodeList.getNodeType() == JsonNodeType.ARRAY) {
                for (JsonNode node : nodeList) {
                    collection.add(readBizOperation(node));
                }
            }
            while (parser.getCurrentToken() == null) {
                parser.nextToken();
            }
            if (parser.getCurrentToken() == JsonToken.END_ARRAY) {
                SerializerUtils.readEndArray(parser);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return collection;
    }

    private ViewModelAction readBizOperation(JsonNode node) {
        String typeJson = node.get("Type").textValue();
        ViewModelActionType type = ViewModelActionType.valueOf(typeJson);
        VmActionDeserializer deserializer = createDeserializer(type);

        SimpleModule module = new SimpleModule();
        module.addDeserializer(ViewModelAction.class, deserializer);
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(module);
        try {
            return mapper.readValue(node.toString(), ViewModelAction.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private VMActionCollection createCollection() {
        return new VMActionCollection();
    }

    private VmActionDeserializer createDeserializer(ViewModelActionType type) {
        switch (type) {
            case BEAction:
                return new MappedBizActionDeserializer();
            case VMAction:
                return new MappedCdpActionDeserializer();
            default:
                throw new RuntimeException();
        }
    }
}
